package com.team2.cyber_eye.ActivityHelpers;

import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URL;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.List;
import javax.xml.parsers.DocumentBuilderFactory;
import org.w3c.dom.Document;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.app.ActivityManager.MemoryInfo;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Color;
import android.graphics.Matrix;
import android.graphics.drawable.Drawable;
import android.location.Address;
import android.location.Criteria;
import android.location.Geocoder;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.media.ExifInterface;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.net.Uri;
import android.view.ContextThemeWrapper;
import android.view.View;
import android.widget.Spinner;
import android.widget.SpinnerAdapter;
import android.widget.TextView;
import android.widget.Toast;

import com.team2.cyber_eye.R;

public class Util {

	final static String[] Hex = {"0","1","2","3","4","5","6","7","8","9","a","b","c","d","e","f"};

	private static final boolean debugMode = true;
	private static double latitude = 0;
	private static double logitude = 0;
	private static boolean isGPSEnabled = false;
	private static Uri imageUri;
	private static boolean internetConnected;
	private static File iqeBitmapFile;
	private static boolean taskCompleted = false;
	
	
	public static String HexConvert(byte[] byteArray)
	{
		String result = "";
		for(int itr = 0; itr < byteArray.length; itr++)
		{
			result += Hex[(byteArray[itr]>>4) & 0xf] + Hex[byteArray[itr] & 0xf];
		}
		return result;
	}
	
	@SuppressLint("SimpleDateFormat")
	public static String getDateString()
	{
	    Calendar calendar = GregorianCalendar.getInstance(); 
	    Date dateNow = calendar.getTime();
	    String dateString = new SimpleDateFormat("yyyyMMddHHmmss").format(dateNow);
	    
	    return dateString;
	}

	public static String ReadFullStream(InputStream stream) throws IOException
	{
		String streamString = "";
		
	    byte[] Data = new byte[1024];
	    
	    int dataLength = stream.read(Data);
	    while (dataLength > 0)
	    {
	    	String subStr = new String(Data);
	    	streamString += subStr;

		    dataLength = stream.read(Data);
	    }
	    
	    return streamString;
	}
	
	public static String FilePath(Uri uri){
		
		String originalPath = "";
		
		originalPath = uri.toString().replace("file://", "");
		
		return originalPath;
		
	}
	
	public static Bitmap decodeSampledBitmapFromResourceMemOpt(
            InputStream inputStream, int reqWidth, int reqHeight) {

        byte[] byteArr = new byte[0];
        byte[] buffer = new byte[1024];
        int len;
        int count = 0;

        try {
            while ((len = inputStream.read(buffer)) > -1) {
                if (len != 0) {
                    if (count + len > byteArr.length) {
                        byte[] newbuf = new byte[(count + len) * 2];
                        System.arraycopy(byteArr, 0, newbuf, 0, count);
                        byteArr = newbuf;
                    }

                    System.arraycopy(buffer, 0, byteArr, count, len);
                    count += len;
                }
            }

            final BitmapFactory.Options options = new BitmapFactory.Options();
            options.inJustDecodeBounds = true;
            BitmapFactory.decodeByteArray(byteArr, 0, count, options);

            options.inSampleSize = calculateInSampleSize(options, reqWidth,
                    reqHeight);
            options.inPurgeable = true;
            options.inInputShareable = true;
            options.inJustDecodeBounds = false;
            options.inPreferredConfig = Bitmap.Config.ARGB_8888;

            return BitmapFactory.decodeByteArray(byteArr, 0, count, options);

        } catch (Exception e) {
            e.printStackTrace();

            return null;
        }
    }
	
	public static int calculateInSampleSize(
            BitmapFactory.Options options, int reqWidth, int reqHeight) {
		    // Raw height and width of image
		    final int height = options.outHeight;
		    final int width = options.outWidth;
		    int inSampleSize = 1;
		
		    if (height > reqHeight || width > reqWidth) {
		
		        // Calculate ratios of height and width to requested height and width
		        final int heightRatio = Math.round((float) height / (float) reqHeight);
		        final int widthRatio = Math.round((float) width / (float) reqWidth);
		
		        // Choose the smallest ratio as inSampleSize value, this will guarantee
		        // a final image with both dimensions larger than or equal to the
		        // requested height and width.
		        inSampleSize = heightRatio < widthRatio ? heightRatio : widthRatio;
		    }
		
		    return inSampleSize;
	}

	public static Document ParseXMLString(String xmlString) throws Exception
	{
	    InputStream xmlInputStream = new ByteArrayInputStream(xmlString.getBytes("UTF-8"));
	    Document xmlDoc = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(xmlInputStream);
	    xmlInputStream.close();
	    
	    return xmlDoc;
	}
	
	public static void TrySleep(long milliSeconds)
	{
		try{Thread.sleep(milliSeconds);}catch(Exception ex){}
	}
	
	public static Bitmap LimitBitmap(Bitmap bmp, int maxSize)
	{

		int width = bmp.getWidth();
		int height = bmp.getHeight();
	        
		if (width > maxSize || height > maxSize)
		{
			 int largeSize = Math.max(width, height);
			 float Scale = (float)maxSize / (float)largeSize;
			 width = (int)Math.floor(Scale * width);
			 height = (int)Math.floor(Scale * height);

			 if (width >= maxSize) width = maxSize;
			 if (height >= maxSize) height = maxSize;
			 
			 bmp = Bitmap.createScaledBitmap(bmp, width, height, true);
		}
		
		return bmp;
	}
	
	public static Bitmap ReduceBitmap(Context con, Uri imageUri, int size){
		Bitmap pictureBitmap = null;
		
		InputStream is;
		try {
			is = con.getContentResolver().openInputStream(imageUri);
			Bitmap bmp = BitmapFactory.decodeStream(is);
			pictureBitmap = Util.LimitBitmap(bmp, size);
		} catch (FileNotFoundException e) {
			Util.DisplayMessage(con, "Error compressing image");
		}
				
		return pictureBitmap;
	}
	
	public static Bitmap LoadBitmapFromUrl(Context con, String UrlPath)
	{
		Bitmap bmp = null;
		try {
			URL bmpURL = new URL(UrlPath);
			InputStream bmpIS = (InputStream)bmpURL.getContent();
			
			bmp = BitmapFactory.decodeStream(bmpIS);
		}
		catch (Exception ex) {
			ex.toString();
			bmp = null;
		}
		
		if (bmp == null)
		{
			Resources res = con.getResources();
			bmp = BitmapFactory.decodeResource(res, R.drawable.no_image);
		}
		
		return bmp;
	}
	
	public static double[] GetLongitugeLatitude(Context con)
	{
		try
		{
			//latitude and logitude always returned as zero
			/*LocationManager locationManager = (LocationManager)con.getSystemService(Context.LOCATION_SERVICE); 
			Location location = locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER);*/
			double[] lonlat = new double[2];
			lonlat[0] = getLogitude();
			lonlat[1] = getLatitude();
			
			return lonlat;
		}
		catch (Exception ex)
		{
			return new double[2];
		}
	}
	
	public static String getZipCode(Context con)
	{
		Geocoder geocoder = new Geocoder(con);
		try
		{
			double[] longlat = Util.GetLongitugeLatitude(con);
			
			List<Address> alist = geocoder.getFromLocation(longlat[0], longlat[1], 1);
			Address address = alist.get(0);
			return address.getPostalCode();
		}
		catch (Exception ex)
		{
			return "";
		}
	}
	
	private static Toast CreateToast(Context con, String message)
	{
		Toast toast;
		toast = Toast.makeText(con.getApplicationContext(), message, Toast.LENGTH_LONG);
		View view = toast.getView();
		
		return toast;
	}

	public static void DisplayMessage(Context con, String message)
	{
		try
		{
			CreateToast(con, message).show();
		}
		catch (Exception ex2)
		{
			System.err.println("--------------------------------");
			System.err.println("DisplayMessage messed up!");
			System.err.println("--------------------------------");
			ex2.printStackTrace();
		}
	}
	
	public static void DisplayIssue(Context con, String message)
	{
		try
		{
			CreateToast(con, message).show();
		}
		catch (Exception ex2)
		{
			System.err.println("--------------------------------");
			System.err.println("DisplayIssue messed up!");
			System.err.println("--------------------------------");
			ex2.printStackTrace();
		}
	}
	
	public static void DisplayError(Context con, String message, Exception ex)
	{
		try
		{
			if (debugMode) 
				CreateToast(con, message + "\n\n" + ex.toString()).show();
			else 
				CreateToast(con, message);
		}
		catch (Exception ex2)
		{
			System.err.println("--------------------------------");
			System.err.println("DisplayError messed up!");
			System.err.println("--------------------------------");
			ex2.printStackTrace();
		}
	}
	
	public static void LogError(Exception ex)
	{
		ex.printStackTrace();
	}
	
	
    public static void CopyStream(InputStream is, OutputStream os)
    {
        final int buffer_size=1024;
        try
        {
            byte[] bytes=new byte[buffer_size];
            for(;;)
            {
              int count=is.read(bytes, 0, buffer_size);
              if(count==-1)
                  break;
              os.write(bytes, 0, count);
            }
        }
        catch(Exception ex){}
    }
    
    
    public static boolean CheckInternet(Context con)
    {
		ConnectivityManager conMan = (ConnectivityManager) con.getSystemService(Context.CONNECTIVITY_SERVICE);
		NetworkInfo ni = conMan.getActiveNetworkInfo();
		if (ni == null)
		{
			DisplayIssue(con, "No Internet Connection");
			
			return false;
		}else{			
			return true;
		}
	}
    
    /**
	 * Starts to gather location data from the finest allowed location provider.
	 * For this to work either one of the following permissions has to be set:
	 * ACCESS_COARSE_LOCATION, ACCESS_FINE_LOCATION.
	 */
	public static void StartLocationGathering(Context con, LocationListener locationListener) {
        LocationManager locationManager = 
            (LocationManager) con.getSystemService(Context.LOCATION_SERVICE);
        
        /*Criteria criteria = new Criteria();
        criteria.setAccuracy(Criteria.ACCURACY_FINE);*/
       
        boolean gpsIsEnabled = locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER);
        boolean networkIsEnabled = locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER);
         
        if(gpsIsEnabled)
        {
            locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 5000L, 10F, locationListener);
        }
        else if(networkIsEnabled)
        {
            locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 5000L, 10F, locationListener);
        }
        
        Location location = locationManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
        
        if(location != null){
        	Util.setLatitude(location.getLatitude());
        	Util.setLogitude(location.getLongitude());
        }
            
        //locationManager.requestLocationUpdates(provider, 5, 5, locationListener);   
        
        /*String provider = locationManager.getBestProvider(criteria, true);
        
        if (provider != null) {
               
        }*/
	}
	
	public static boolean isGPSEnabled(final Activity con){
		LocationManager locationManager = 
	            (LocationManager) con.getSystemService(Context.LOCATION_SERVICE);
	        
	        Criteria criteria = new Criteria();
	        criteria.setAccuracy(Criteria.ACCURACY_FINE);
	        
	        String provider = locationManager.getBestProvider(criteria, true);
	        
	        if(provider == null){
	        	isGPSEnabled = locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER);
	        }else{
	        	isGPSEnabled = locationManager.isProviderEnabled(provider);
	        }
	        
	        if(!isGPSEnabled){
	        	new AlertDialog.Builder(new ContextThemeWrapper(con, R.style.Theme_MyDialog))
	            .setIcon(android.R.drawable.ic_dialog_alert)
	            .setTitle("")
	            .setMessage("Enable GPS for nearest Store Location?")
	            .setPositiveButton("Yes", new DialogInterface.OnClickListener()
		        {
		            @Override
		            public void onClick(DialogInterface dialog, int which) {
		            	con.startActivityForResult(new Intent(android.provider.Settings.ACTION_LOCATION_SOURCE_SETTINGS), 
		            			5);    
		            }
		
		        })
		        .setNegativeButton("No", null)
		        .show();
	        }
	        
	        return isGPSEnabled;
	}

	public static double getLatitude() {
		return latitude;
	}

	public static double getLogitude() {
		return logitude;
	}
	
	public static void setLatitude(double latitude) {
		Util.latitude = latitude;
	}

	public static void setLogitude(double logitude) {
		Util.logitude = logitude;
	}

	public static void SetSpinnerTo(Spinner spinner, String Target)
	{
		SpinnerAdapter adapter = spinner.getAdapter();
		
		if (adapter != null)
			for(int itr = 0; itr < adapter.getCount(); itr++)
			{
				String str = (String)adapter.getItem(itr);
				if (Target.equals(str))
				{
					spinner.setSelection(itr);
					return;
				}
			}
		
		spinner.setSelection(0);
	}
	
	public static Bitmap RotateBitmap(Bitmap bmp, String filePath){
		
		Bitmap rotatedBitmap = null;
		boolean rotationChanged = false;
		
		try{
			Matrix matrix = new Matrix();

			ExifInterface exifReader = new ExifInterface(filePath);

			int orientation = exifReader.getAttributeInt(ExifInterface.TAG_ORIENTATION, -1);

			if (orientation ==ExifInterface.ORIENTATION_NORMAL) {

			      // Do nothing. The original image is fine.

			} else if (orientation == ExifInterface.ORIENTATION_ROTATE_90) {

				rotationChanged = true;
			       matrix.postRotate(90);

			} else if (orientation == ExifInterface.ORIENTATION_ROTATE_180) {

				rotationChanged = true;
			       matrix.postRotate(180);

			} else if (orientation == ExifInterface.ORIENTATION_ROTATE_270) {

				rotationChanged = true;
			      matrix.postRotate(270);

			}
			
			if(rotationChanged){
				rotatedBitmap = Bitmap.createBitmap(bmp, 0, 0, 
						bmp.getWidth(), bmp.getHeight(), matrix, true);
			}
			
		}catch(IOException e){
			Util.LogError(e);
		}
		return rotatedBitmap;
	}

	public static boolean isInternetConnected() {
		return internetConnected;
	}

	public static void setInternetConnected(boolean internetConnected) {
		Util.internetConnected = internetConnected;
	}

	public static File getIqeBitmapFile() {
		return iqeBitmapFile;
	}

	public static void setIqeBitmapFile(File iqeBitmapFile) {
		Util.iqeBitmapFile = iqeBitmapFile;
	}

	public static boolean isTaskCompleted() {
		return taskCompleted;
	}

	public static void setTaskCompleted(boolean taskCompleted) {
		Util.taskCompleted = taskCompleted;
	}
}
